/**
 * @file 进程管理器
 * @description 负责管理和监控应用进程信息
 * @author 黄敏
 * @version 1.0.0
 * @since 2025-07-09
 */

import type { Process, ProcessDetail } from '~types/common'
import { app, ipcMain, webContents } from 'electron'
import { processTopic } from '~shared/ipc-topic'

/**
 * 进程管理器类
 * @description 提供进程信息获取、格式化和监控功能
 */
export class ProcessManager {
  private static instance: ProcessManager | null = null

  /**
   * 私有构造函数，确保单例模式
   */
  private constructor() {
    this.setupIpcHandlers()
  }

  /**
   * 获取单例实例
   */
  static getInstance(): ProcessManager {
    if (!ProcessManager.instance) {
      ProcessManager.instance = new ProcessManager()
    }
    return ProcessManager.instance
  }

  /**
   * 获取进程详细信息
   * @returns 包含所有进程信息的详细数据
   */
  getProcessDetails(): ProcessDetail {
    const webContentsList = webContents.getAllWebContents()

    // 创建进程ID到窗口标题的映射
    const processIdToTitle: Record<string, string> = {}

    for (const webContent of webContentsList) {
      const processId = webContent.getOSProcessId().toString()
      processIdToTitle[processId] = webContent.getTitle().replace(/localhost:\d{4}\/#?\/|#\/$/g, '')
    }

    let totalMemory = 0
    let totalCpu = 0

    // 获取应用进程指标并格式化
    const processes: Process[] = app.getAppMetrics().map(metric => {
      const memoryBytes = metric.memory.privateBytes ?? 0
      const cpuUsage = metric.cpu.percentCPUUsage

      totalMemory += memoryBytes
      totalCpu += cpuUsage

      return {
        pid: metric.pid,
        type: metric.type,
        name: processIdToTitle[metric.pid.toString()] || metric.name,
        cpu: cpuUsage.toFixed(2),
        creationTime: metric.creationTime,
        memory: this.formatMemoryUsage(memoryBytes),
        sandboxed: metric.sandboxed
      }
    })

    return {
      totalCpu: totalCpu.toFixed(2),
      totalMemory: this.formatMemoryUsage(totalMemory),
      process: processes
    }
  }

  /**
   * 清理资源
   */
  cleanup(): void {
    // 移除IPC处理器
    ipcMain.removeHandler(processTopic.get)
  }

  /**
   * 格式化内存使用量
   * @param bytes - 字节数
   * @returns 格式化后的内存字符串
   */
  private formatMemoryUsage(bytes: number): string {
    const mb = bytes / 1024
    return `${mb.toFixed(2)}MB`
  }

  /**
   * 设置IPC处理器
   * @private
   */
  private setupIpcHandlers(): void {
    // 处理获取进程详细信息的请求
    ipcMain.handle(processTopic.get, () => {
      return this.getProcessDetails()
    })
  }
}

// 导出单例实例
export const processManager = ProcessManager.getInstance()
